/**
 * axios二次封装
 */
import axios from 'axios'; // 是一个基于 Promise 的 HTTP 客户端，用于发送网络请求。
import config from './../config';  // 从 config 模块导入配置信息，包含 API 基础地址、是否使用模拟数据等配置。
import { ElMessage } from 'element-plus' // ElementPlus 组件库中的消息提示组件，用于显示错误消息。
import router from './../router' // 导入路由实例，用于在 token 失效时进行页面跳转。
import storage from './storage' // 用于操作本地存储，封装了 localStorage, sessionStorage 的工具。

// 定义错误提示信息常量
const TOKEN_INVALID = 'Token认证失败，请重新登陆'
const NETWORK_ERROR = '网络请求异常，请稍后重试'

//创建axios实例对象，添加全局配置
const service = axios.create({
    baseURL:config.baseApi,
    timeout: 8000
})

//请求拦截
service.interceptors.request.use((req)=>{ // 用于添加请求拦截器，在请求发送之前进行一些处理
    const headers = req.headers;
    const { token = "" } = storage.getItem('userInfo')  || {};
    if(!headers.Authorization) headers.Authorization = 'Bearer ' + token;
    return req;
})

//响应拦截
service.interceptors.response.use((res)=>{ // 用于添加响应拦截器，在接收到响应后进行一些处理。
    console.log('响应数据:', res.data); // 打印响应数据
    const { code, data, msg } = res.data;
    // 根据code来执行，code200表示正确响应返回对应数据，其他code为报错
    if(code == 200){
        return  data;
    }else if(code === 500001){
        ElMessage.error(TOKEN_INVALID)
        setTimeout(()=>{
            router.push('/login')
        }, 1500)

        return Promise.reject(TOKEN_INVALID)
    }else{
        ElMessage.error(msg || NETWORK_ERROR)
        return Promise.reject(msg || NETWORK_ERROR)
    }
})

/**
 * 请求核心函数
 * @param {*} options 请求配置
 * @returns 
 */
function request(options){  // 接收一个 options 对象作为请求配置
    options.method = options.method || 'get'  // 如果 options 中没有指定 method，则默认使用 get 方法。
    if(options.method.toLowerCase() === 'get'){  // 如果是 get 请求，将 options.data 赋值给 options.params。
        options.params = options.data;
    }

    let isMock = config.mock;  // 根据 config 中的 mock 配置和 options 中的 mock 选项，决定是否使用模拟数据。
    let isModel = config.model;
    if(typeof options.mock != 'undefined'){
        isMock = options.mock;
    }
    // 如果是生产环境（config.env === 'prod'），则使用 config.baseApi 作为基础地址；
    // 否则，根据 isMock 的值选择使用 config.mockApi 或 config.baseApi。
    if(config.env === 'prod'){ 
        if (options.mode == 'baseApi') {
            service.defaults.baseURL = config.baseApi
        }
        else if (options.mode == 'modelApi') {
            service.defaults.baseURL = config.modelApi
        }
        console.log('prod', service.defaults.baseURL)
    } else {
        if (options.mode == 'baseApi') {
            service.defaults.baseURL = config.baseApi
        }
        else if (options.mode == 'mockApi') {
            service.defaults.baseURL = config.mockApi
        }
        else if (options.mode == 'modelApi') {
            service.defaults.baseURL = config.modelApi
        }
        console.log('prod', options.url, config.env, service.defaults.baseURL)
    }
    // 最后调用 service 实例发送请求，并返回一个 Promise
    return service(options) 
}

// 通过 forEach 循环为 request 函数添加 get、post、put、delete 和 patch 方法，方便使用。
['get', 'post', 'put', 'delete', 'patch'].forEach((item)=>{
    request[item] = (url, data, options)=>{  // 这些方法接收 url、data 和 options 作为参数，内部调用 request 函数并传递相应的配置
        return request({
            url, 
            data, 
            method: item,
            ...options
        })
    }
})
// 导出 request 函数
export default request;